#!/usr/bin/env python
# -*- coding: utf-8 -*-

#人脸识别
#通用识别/动物识别/植物识别/蔬菜识别/形状识别
#红绿灯识别
#手写字体抓取
#视觉循迹

import sys
import os
import math
import matplotlib.pyplot as plt
import base64
import json

from aip import AipFace
from aip import AipImageClassify
from aip import AipOcr
import requests


import rospy
from sensor_msgs.msg import Image
from std_msgs.msg import String
from std_srvs.srv import *
from arm_controller.srv import *
from arm_controller.msg import *

import cv2
from cv_bridge import CvBridge, CvBridgeError



# 定义id等
APP_ID = '22423119'
API_KEY = 'pGVCDA9SkskLMH3jcv1m1kI6'
SECRET_KEY = 'H2YpAmVki3xFY1qfcD9xkeqk027zhQNh'

class image_converter(object):
	aipFace = ''
	aipclassify = ''
	image_pub = ''
	flag = ''
	client = ''
	r =''
	j=''
	access_token=''
	def __init__(self):
		# 创建cv_bridge，声明图像的发布者和订阅者
		self.image_pub = rospy.Publisher("cv_bridge_image", Image, queue_size=1)
		self.bridge = CvBridge()
		self.image_sub = rospy.Subscriber("/usb_cam/image_raw", Image, self.callback)
		#人脸识别
		self.aipFace = AipFace(APP_ID, API_KEY, SECRET_KEY)
		#图像识别
		s0=rospy.Service('universal',SetBool,self.universal_callback)
		s1=rospy.Service('animal',SetBool,self.animal_callback)
		s2=rospy.Service('plant',SetBool,self.plant_callback)
		s3=rospy.Service('vegetables',SetBool,self.vegetables_callback)
		s4=rospy.Service('shape',SetBool,self.shape_callback)
		s5=rospy.Service('number',number,self.number_callback)
		s6=rospy.Service('face',SetBool,self.face_callback)

		self.aipclassify=AipImageClassify(APP_ID, API_KEY, SECRET_KEY)

		self.client = AipOcr(APP_ID, API_KEY, SECRET_KEY)

		self.flag = 100

	def face_callback(self,req):
		def get_file_content(filePath):
			with open(filePath, 'rb') as fp:
				return fp.read()

		image = get_file_content('/home/fox/.ros/ai.jpg')
		cv_image = cv2.imread('/home/fox/.ros/ai.jpg')
	
		imageType = "BASE64"
		options = {}
		options["face_field"] = "age"
		options["max_face_num"] = 10
		options["face_type"] = "LIVE"
		result = self.aipFace.detect(image, imageType, options)

		print result

		
		#解析位置信息
		face_num = result['result']['face_num']
		
		for num in range(0,int(face_num)):
			print(num)
			location = result['result']['face_list'][num-1]['location']

			left_top = (int(location['left']),int(location['top']))
			right_bottom = (left_top[0]+int(location['width']),left_top[1]+int(location['height']))
			cv2.rectangle(cv_image,left_top, right_bottom, (0,0,255),2)
		
		cv2.imwrite('/home/fox/.ros/number.jpg', cv_image)

		return(True,"success")
		

	#通用物体识别
	def universal_callback(self,req):
		def get_file_content(filePath):
			with open(filePath, 'rb') as fp:
				return fp.read()

		image = get_file_content('/home/fox/.ros/ai.jpg')

		options = {}
		options["baike_num"] = 5
		result = self.aipclassify.advancedGeneral(image, options)
		# print(result)
		# print(type(result))

		class_num = result['result_num']
		str1 = u"共发现物品标签: "

		for num in range(0,int(class_num)):
			strn = result['result'][num-1]['keyword']
			str1 = str1 + strn
			str1 = str1 + u" / "
		print str1
		return(True,"success")

	#动物识别
	def animal_callback(self,req):
		def get_file_content(filePath):
			with open(filePath, 'rb') as fp:
				return fp.read()

		image = get_file_content('/home/fox/.ros/ai.jpg')

		options = {}
		options["top_num"] = 3
		options["baike_num"] = 5
		result = self.aipclassify.animalDetect(image, options)
		# print(result)
		# print(type(result))

		class_num = len(result['result'])
		str1 = u"共发现动物: "
		for num in range(0,int(class_num)):
			strn = result['result'][num-1]['name']
			str1 = str1 + strn
			str1 = str1 + u" / "
		print str1
		return(True,"success")
		
	#植物识别
	def plant_callback(self,req):
		def get_file_content(filePath):
			with open(filePath, 'rb') as fp:
				return fp.read()

		image = get_file_content('/home/fox/.ros/ai.jpg')

		options = {}
		options["baike_num"] = 5
		result = self.aipclassify.plantDetect(image, options)
		print(result)
		print(type(result))

		class_num = len(result['result'])
		str1 = u"共发现植物: "
		for num in range(0,int(class_num)):
			strn = result['result'][num-1]['name']
			str1 = str1 + strn
			str1 = str1 + u" / "
		print str1
		return(True,"success")

	#蔬菜识别
	def vegetables_callback(self,req):
		def get_file_content(filePath):
			with open(filePath, 'rb') as fp:
				return fp.read()

		image = get_file_content('/home/fox/.ros/ai.jpg')

		options = {}
		options["top_num"] = 3
		result = self.aipclassify.ingredient(image, options)
		print(result)
		print(type(result))

		class_num = result['result_num']
		str1 = u"共发现蔬菜: "
		for num in range(0,int(class_num)):
			strn = result['result'][num-1]['name']
			str1 = str1 + strn
			str1 = str1 + u" / "
		print str1
		return(True,"success")

	#形状识别
	def shape_callback(self,req):
		def get_file_content(filePath):
			with open(filePath, 'rb') as fp:
				return fp.read()

		image = get_file_content('/home/fox/.ros/ai.jpg')

		options = {}
		options["with_face"] = 0
		result = self.aipclassify.objectDetect(image, options)
		print(result)
		print(type(result))

		location = result['result']
		left_top = (int(location['left']),int(location['top']))
		right_bottom = (left_top[0]+int(location['width']),left_top[1]+int(location['height']))

		cv_image = cv2.imread('/home/fox/.ros/ai.jpg')
		cv2.rectangle(cv_image,left_top, right_bottom, (255,0,0),2)
		cv2.imwrite('/home/fox/.ros/shape.jpg', cv_image)

		# class_num = result['result_num']
		# str1 = u"共发现蔬菜: "
		# for num in range(0,int(class_num)):
		# 	strn = result['result'][num-1]['name']
		# 	str1 = str1 + strn
		# 	str1 = str1 + u" / "
		# print str1
		return(True,"success")

	#手写数字识别
	def number_callback(self,req):
		def get_file_content(filePath):
			with open(filePath, 'rb') as fp:
				return fp.read()

		image = get_file_content('/home/fox/.ros/ai.jpg')

		options = {}
		options["recognize_granularity"] = "big"
		options["detect_direction"] = "true"
		options["vertexes_location"] = "true"
		options["probability"] = "true"
		result = self.client.handwriting(image)
		#result = self.client.numbers(image)
		print(result)
		print(type(result))


		if result['words_result_num']>0:
			location = result['words_result']
			num = result['words_result_num']
			cv_image = cv2.imread('/home/fox/.ros/ai.jpg')


			numberlist = []
			poselist = []

			for i in range(num):
				print location[i]['words']
				print " "
				locc = location[i]['location']
				
				left_top = (int(locc['left']),int(locc['top']))
				right_bottom = (left_top[0]+int(locc['width']),left_top[1]+int(locc['height']))

				cv2.rectangle(cv_image,left_top, right_bottom, (255,0,0),2)
				print "x = "
				print ((left_top[1]+right_bottom[1])/2.0 - 55)*0.3056 + 152
				print left_top
				print "y = "
				print ((left_top[0]+right_bottom[0])/2.0 - 315.5) *0.30275
				print right_bottom
				numberlist.append(i)
				pose = control()
				pose.position.x = ((left_top[1]+right_bottom[1])/2.0 - 55)*0.3056 + 152
				pose.position.y = ((left_top[0]+right_bottom[0])/2.0 - 315.5) *0.30275
				pose.position.z = 3
				poselist.append(pose)
				
			cv2.imwrite('/home/fox/.ros/number.jpg', cv_image)

			return numberResponse(True,numberlist,poselist)
		else:
			print "Not found"
			return numberResponse(False,numberlist,poselist)


	def callback(self,data):
        # 使用cv_bridge将ROS的图像数据转换成OpenCV的图像格式
		self.flag += 1

		if self.flag%10 == 0:
			try:
				cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
				cv2.imwrite('/home/fox/.ros/ai.jpg', cv_image)
			except CvBridgeError as e:
				print " "
				#print e

			filepath = "/home/fox/.ros/ai.jpg"
			with open(filepath, "rb") as fp:
				base64_data = base64.b64encode(fp.read())
			base64_data = str(base64_data)
			imageType = "BASE64"
			cv_image = cv2.imread(filepath)

			options = {}
			options["face_field"] = "age"
			options["max_face_num"] = 10
			options["face_type"] = "LIVE"
			result = self.aipFace.detect(base64_data, imageType, options)
			# print(result)
			# print(type(result))
			if result['error_msg'] == "SUCCESS" :
				face_num = result['result']['face_num']


				for num in range(0,int(face_num)):
					# print(num)
					location = result['result']['face_list'][num-1]['location']
					# print(location)

					left_top = (int(location['left']),int(location['top']))
					right_bottom = (left_top[0]+int(location['width']),left_top[1]+int(location['height']))
					cv2.rectangle(cv_image,left_top, right_bottom, (255,0,0),2)

					str1 = "face " + str(num) 
					cv2.putText(cv_image, str1, left_top, cv2.FONT_HERSHEY_COMPLEX, 0.6, (0, 0, 255), 1)
					str1 = "age : " + str(result['result']['face_list'][num-1]['age'])
					left_top = (int(location['left']),int(location['top']+20))
					cv2.putText(cv_image, str1, left_top, cv2.FONT_HERSHEY_COMPLEX, 0.6, (0, 0, 255), 1)

			# 显示Opencv格式的图像
			# cv2.imshow("Image window", cv_image)
			# cv2.waitKey(3)

			# 再将opencv格式额数据转换成ros image格式的数据发布
			try:
			    self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
			except CvBridgeError as e:
				print " "
			    #print e

if __name__ == '__main__':
	try:
		# 初始化ros节点
		rospy.init_node("face_ai")
		rospy.loginfo("Starting face_ai node")
		image = image_converter()
		rospy.spin()
	except KeyboardInterrupt:
		print "Initialization failed."
		cv2.destroyAllWindows()
